Since version 1.7.6 - and in production since the version 1.9.0, BigDFT uses YAML markup language to handle I/O of the code. For an overview of yaml specifications see this page. This adds much flexibility as new input variables might be added without altering the format of the input files, in a transparent way for all the users. Here we follow the steps needed to add such input file in the code.

Essentially, a new input variable shoudl correspond to a set of ultimate components of the input_variables datatype, that is defined in the module module_input_keys (file input_keys.f90)in the directory src/modules).

As an example, imagine we would like to insert a logical variable to control the calculation of the stress tensor at the end of the SCF cycle. Obviuosly, we should start by adding the component in the input_variables datatype:

!> Structure of the variables read by input.* files
  type, public :: input_variables
     !>reference counter
     type(f_reference_counter) :: refcnt
     !> enumerator for the mode of the run
     type(f_enumerator) :: run_mode
     [...]
     !> boolean to activate the calculation of the stress tensor
     logical :: calculate_strten
     [...]
  end type input_variables

Note also the adding of the Doxygen documentation, for code review. This variable should also be initialized in the default_input_variables routine, if default initialization is important.

Insert the variable in input_variables_definition.yaml file and associate a keyword

The input variables themselves are defined and parsed in YAML format within the libbigdft-1.a library. This allows the code to have an automatic determination of the allowed ranges and values of the parameters, within the guidelines defined in the f_input_file module of the flib utilities tool.

Coming back to our example, let us now insert the keyword associated to this variable in the file input_variables_definition.yaml, presently in the src/ directory. To do that, one should follow the instructions written at the beginning of such file. Let us now add the specification of the input variable (rigorously in lowercase format, to avoid typing problems). In this example, we have

calculate_strten:
  COMMENT: Boolean to activate the calculation of the stress tensor. Might be set to No for performance reasons
  DESCRIPTION: In some cases, for example when doing MD for fixed volume systems, il might be useful to disable the
                 calculation of the stress tensor, to save computational time
  default: Yes

Again, see the instruction at the beginning of the file for all the possible fields and descriptions.

Now that this variable has been inserted, a keyword has to be associated to it. In other terms, we have to say the code that the string calculate_strten is important whilst parsing the input file. To do that, simply add a new parameter in the public_keys.f90 module (directory /src/orbitals):

   [...]
character(len = *), parameter :: CALCULATE_STRTEN = "calculate_strten"
   [...]

To invoke the input variable, we will now use the CALCULATE_STRTEN parameter. This is much safer that using the string variable directly as typos will be deteceted at compile time as we would refer to the parameter.

Retrieve the value of the variable as parsed from the input file

One the above steps have been performed, the code is able to parse the value of the calculate_strten variable. This means that, if now the input file contains such keyword (that has been placed in the dft field for this example), no error is raised. Now we have to associate the value of the variable as it is parsed from the input file into the value of the ultimate component of the input_variables structure. The point to do that is the input_set_dict routine, in the input_keys.f90 file.

   [...]
case(CALCULATE_STRTEN)
  in%calculate_strten=val
   [...]

The parsed value is stored in the variable val, and it can be affected to the calculate_strten utilmate component. Clearly the assignment operator is understanding an overload which is taking care of the fact that the two entities have different type. Then the input variable is stored and the developer is able to invoke it from the input_variables datatype.